package ru.org.conversion.localization;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import ru.org.conversion.logging.LoggingConstants;

/**
 * Application text resources.
 */
public enum R {

	MESSAGES("messages");

	private static final String DEFAULT_VALUE = "";

	private final Logger log = LogManager
			.getLogger(LoggingConstants.LOGGER_APP);

	private ResourceBundle bundle;

	private R(String bundleName) throws MissingResourceException {
		if (bundleName == null) {
			log.fatal("Cannot get resource bundle: the name is not specified!");
			throw new NullPointerException("bundle name");
		}
		try {
			this.bundle = ResourceBundle.getBundle(bundleName);
		} finally {
			if (bundle == null) {
				log.fatal("Cannot find resource bundle for name {}!",
						bundleName);
				throw new IllegalArgumentException("The name " + bundleName
						+ " is not a valid resource bundle name!");
			}
		}
	}

	private String getFormattedString(String key, String defaultValue,
			Object... params) {

		if (key == null) {
			throw new NullPointerException("resource key");
		}

		try {
			return MessageFormat.format(bundle.getString(key), params);
		} catch (MissingResourceException ex) {
			log.error("Cannot find simple value for key {}", key);
		} catch (IllegalArgumentException ex) {
			log.error("Cannot find simple value for key {}", key);
		}
		return defaultValue;
	}

	private String getString(String key, String defaultValue) {

		if (key == null) {
			throw new NullPointerException("resource key");
		}

		try {
			return bundle.getString(key);
		} catch (MissingResourceException ex) {
			log.error("Cannot find formatted value for key {}", key);
			return defaultValue;
		}
	}

	/**
	 * Gets a plain string from resources for the specified key.
	 * 
	 * @param key
	 *            string key
	 * @return the value from the resources or an empty value if there is no one
	 *         for the specified key.
	 * @throws NullPointerException
	 *             if key is <code>null</code>
	 */
	public static String get(String key) {
		return MESSAGES.getString(key, DEFAULT_VALUE);
	}

	/**
	 * Gets a formatted string value for the specified key using the array of
	 * parameters.
	 * 
	 * @param key
	 *            string key
	 * @param params
	 *            array of parameters for substituting placeholders in the
	 *            value.
	 * @return the value for the specified key with the parameters substituted
	 *         with the <b>params</b> elements or an empty value of no such key
	 *         was found.
	 * @throws NullPointerException
	 *             if the key is <code>null</code>
	 * @throws IllegalArgumentException
	 *             if the value itself is invalid
	 */
	public static String get(String key, Object... params) {
		return MESSAGES.getFormattedString(key, DEFAULT_VALUE, params);
	}
}